package com.spark.lola.support.wms.util;

import cn.jiguang.common.ClientConfig;
import cn.jiguang.common.ServiceHelper;
import cn.jiguang.common.connection.NettyHttpClient;
import cn.jiguang.common.resp.APIConnectionException;
import cn.jiguang.common.resp.APIRequestException;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Options;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.AndroidNotification;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;
import com.alibaba.fastjson.JSONObject;
import com.spark.lola.support.wms.configuration.JPushProperties;
import com.spark.lola.support.wms.constant.JPushType;
import com.spark.lola.support.wms.dto.JPushSendDto;
import io.netty.handler.codec.http.HttpMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: Zhi-peng wang
 * @date: 2020/05/13 16:01
 * 极光推送工具类
 **/
@Component
public class JPushUtil {

    private static final Logger logger = LoggerFactory.getLogger(JPushUtil.class);

    /**
     * @description: 使用 NettyHttpClient 异步接口发送请求
     * @author: wzp
     * @date: 2020/5/13
     */
    public void sendPushWithCallback(JPushProperties.Config config, JPushSendDto jPushSendDto) {
        ClientConfig clientConfig = ClientConfig.getInstance();
        clientConfig.setTimeToLive(config.getTimeToLive());
        String host = (String) clientConfig.get(ClientConfig.PUSH_HOST_NAME);
        NettyHttpClient nettyHttpClient = new NettyHttpClient(ServiceHelper.getBasicAuthorization(config.getAppKey(), config.getMasterSecret()), null, clientConfig);
        try {
            URI uri = new URI(host + clientConfig.get(ClientConfig.PUSH_PATH));
            PushPayload pushPayload = JPushType.ALIAS.equals(jPushSendDto.getPushType())
                    ? buildPayLoad_alias(jPushSendDto.getTitle(), jPushSendDto.getContent(), jPushSendDto.getExtrasMap(),
                    jPushSendDto.getPushConditions(), config.getApnsProduction())
                    : buildPayLoad_registrationId(jPushSendDto.getTitle(), jPushSendDto.getContent(),
                    jPushSendDto.getExtrasMap(), jPushSendDto.getPushConditions(), config.getApnsProduction());
            nettyHttpClient.sendRequest(HttpMethod.POST, pushPayload.toString(), uri, responseWrapper -> {
                if (responseWrapper.responseCode != 200) {
                    logger.info("====极光推送 失败：【{}】====", responseWrapper.responseContent);
                } else {
                    logger.info("====极光推送 成功====");
                }
            });
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } finally {
            nettyHttpClient.close();
        }
    }

    public void sendPush(JPushProperties.Config config, JPushSendDto jPushSendDto) {
        ClientConfig clientConfig = ClientConfig.getInstance();
        clientConfig.setTimeToLive(config.getTimeToLive());
        JPushClient jPushClient = new JPushClient(config.getAppKey(), config.getMasterSecret(), null, clientConfig);
        try {
            PushPayload pushPayload = JPushType.ALIAS.equals(jPushSendDto.getPushType())
                    ? buildPayLoad_alias(jPushSendDto.getTitle(), jPushSendDto.getContent(), jPushSendDto.getExtrasMap(),
                    jPushSendDto.getPushConditions(), config.getApnsProduction())
                    : buildPayLoad_registrationId(jPushSendDto.getTitle(), jPushSendDto.getContent(),
                    jPushSendDto.getExtrasMap(), jPushSendDto.getPushConditions(), config.getApnsProduction());
            PushResult result = jPushClient.sendPush(pushPayload);
            logger.info("推送结果：【{}】", result);
        } catch (APIConnectionException e) {
            logger.error("连接失败", e);
        } catch (APIRequestException e) {
            logger.error("Error response from JPush server. Should review and fix it. ", e);
        }

    }

    public PushPayload buildPayLoad_alias(String title, String content, Map<String, String> extrasMap,
                                          List<String> alias, boolean apnsProduction) {
        if (CollectionUtils.isEmpty(extrasMap)) {
            extrasMap = new HashMap<>();
        }
//        JSONObject iosAlertJson = new JSONObject();
//        iosAlertJson.put("title", title);
//        iosAlertJson.put("body", content);

        return PushPayload.newBuilder().setPlatform(Platform.android_ios())
                .setAudience(CollectionUtils.isEmpty(alias) ? Audience.all() : Audience.alias(alias))
                .setNotification(Notification.newBuilder()
                        .addPlatformNotification(
                                IosNotification.newBuilder().setAlert(content).addExtras(extrasMap).build()
                        )
                        .addPlatformNotification(
                                AndroidNotification.newBuilder().setAlert(content).addExtras(extrasMap).build()
                        ).build()
                )
                .setOptions(Options.newBuilder().setApnsProduction(apnsProduction).build()
                )
                .build();
    }

    public PushPayload buildPayLoad_registrationId(String title, String content, Map<String, String> extrasMap,
                                                   List<String> registrationId, boolean apnsProduction) {
        if (CollectionUtils.isEmpty(extrasMap)) {
            extrasMap = new HashMap<>();
        }
        JSONObject iosAlertJson = new JSONObject();
        iosAlertJson.put("title", title);
        iosAlertJson.put("body", content);
        return PushPayload.newBuilder().setPlatform(Platform.android_ios())
                .setAudience(Audience.registrationId(registrationId))
                .setNotification(Notification.newBuilder()
                        .addPlatformNotification(
                                AndroidNotification.newBuilder().setTitle(title).setAlert(content).addExtras(extrasMap).build()
                        )
                        .addPlatformNotification(
                                IosNotification.newBuilder().setAlert(iosAlertJson).addExtras(extrasMap).build()
                        ).build()

                )
                .setOptions(Options.newBuilder().setApnsProduction(apnsProduction).build()
                )
                .build();
    }

}
